﻿using System;
using System.Text;
using System.Security.Cryptography;

namespace EncryptHelpers
{
    class Program
    {
        static void WriteValue(string text, bool newLine)
        {
            var oriColor = Console.ForegroundColor;
            Console.ForegroundColor = ConsoleColor.Yellow;

            Console.Write(text);

            if (newLine)
                Console.WriteLine();

            Console.ForegroundColor = oriColor;
        }

        static void WriteLabel(string text, bool newLine)
        {
            var oriColor = Console.ForegroundColor;
            Console.ForegroundColor = ConsoleColor.Gray;

            Console.Write(text);

            if (newLine)
                Console.WriteLine();

            Console.ForegroundColor = oriColor;
        }

        static void Main(string[] args)
        {
            var methods = new string[] { "exit", "MD5", "SHA1", "SHA256", "SHA384", "SHA512", "RSA", "DES", "3DES" };

            for (int i = 0, l = methods.Length; i < l; i++)
                WriteValue("  " + i.ToString() + " - " + methods[i], true);

            while (true)
            {
                var methodIndex = 0;
                while (true)
                {
                    WriteLabel("\r\nChoose encrypt algorithm: \t", false);

                    var input = Console.ReadLine();
                    if (!int.TryParse(input, out methodIndex) || methodIndex >= methods.Length)
                        continue;

                    if (0 == methodIndex)
                        return;

                    WriteValue(methods[methodIndex], true);
                    break;
                }

                WriteLabel("Enter the text to encrypt: \t", false);
                var textToEncrypt = Console.ReadLine();

                var method = methods[methodIndex];
                if (methodIndex <= 5)
                {
                    var encryptedText = HashHelper.ComputeHash(methods[methodIndex], textToEncrypt, false);
                    WriteLabel("Hash code: \t\t\t", false);
                    WriteValue(encryptedText, true);
                }
                else if (method == "RSA")
                {
                    string publicKey;
                    string privateKey;
                    var rsa = EncryptHelper.RSAHelper.CreateRSACSP(1024, out publicKey, out privateKey);

                    //公钥加密
                    var rsa1 = new RSACryptoServiceProvider(1024);
                    rsa1.FromXmlString(publicKey);

                    var encryptedText = EncryptHelper.RSAHelper.Encrypt(rsa1, textToEncrypt);

                    WriteLabel("Encrypted text: \t\t", false);
                    WriteValue(encryptedText, true);

                    //私钥解密
                    var rsa2 = new RSACryptoServiceProvider(1024);
                    rsa2.FromXmlString(privateKey);

                    var decryptedText = EncryptHelper.RSAHelper.Decrypt(rsa2, encryptedText);
                    WriteLabel("Decrypted text: \t\t", false);
                    WriteValue(decryptedText, true);

                    //私钥加密(sign)
                    var md5 = MD5.Create();
                    var signature = EncryptHelper.RSAHelper.SignData(rsa2, textToEncrypt, md5);
                    WriteLabel("Text signature: \t\t", false);
                    WriteValue(signature, true);

                    //公钥解密(verify)
                    var isValid = EncryptHelper.RSAHelper.VerifyData(rsa1, textToEncrypt, signature, md5);
                    WriteLabel("Data verification result: \t", false);
                    WriteValue(isValid.ToString(), true);
                }
                else if (method == "DES")
                {
                    var des = EncryptHelper.DESHelper.CreateDESCSP();

                    string key;
                    string iv;
                    EncryptHelper.DESHelper.MakeKey(out key, out iv);

                    WriteLabel("DES Key: \t\t\t", false);
                    WriteValue(key, true);
                    WriteLabel("DES IV: \t\t\t", false);
                    WriteValue(iv, true);

                    var encryptedText = EncryptHelper.DESHelper.Encrypt(textToEncrypt, key, iv);
                    WriteLabel("Encrypted text: \t\t", false);
                    WriteValue(encryptedText, true);

                    var decryptedText = EncryptHelper.DESHelper.Decrypt(encryptedText, key, iv);
                    WriteLabel("Decrypted text: \t\t", false);
                    WriteValue(decryptedText, true);
                }
                else
                {
                    var des = EncryptHelper.TripleDESHelper.CreateTripleDESCSP();

                    string key;
                    string iv;
                    EncryptHelper.TripleDESHelper.MakeKey(out key, out iv);

                    WriteLabel("DES Key: \t\t\t", false);
                    WriteValue(key, true);
                    WriteLabel("DES IV: \t\t\t", false);
                    WriteValue(iv, true);

                    var encryptedText = EncryptHelper.TripleDESHelper.Encrypt(textToEncrypt, key, iv);
                    WriteLabel("Encrypted text: \t\t", false);
                    WriteValue(encryptedText, true);

                    var decryptedText = EncryptHelper.TripleDESHelper.Decrypt(encryptedText, key, iv);
                    WriteLabel("Decrypted text: \t\t", false);
                    WriteValue(decryptedText, true);
                }

                Console.WriteLine();
            }
        }
    }
}
